/**
 *  TinyPasswordManager
 *  Copyright (C) 2008 Gross David <gdavid.devel@gmail.com>
 *                     Vinet Guillaume <vinet.guillaume@gmail.com>
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/


#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QtGui/QMainWindow>
#include <QSystemTrayIcon>
#include <QTranslator>

#include "identifier.h"
#include "tinypasswordmanager.h"

namespace Ui {
    class MainWindow;
}

/*!
 * \class MainWindow
 * \brief Main class for TinyPasswordManager GUI with Qt
 *
 * This class implements MainWindow Qt Ui file.
 * Display the window and process actions from it.
 * Extends QMainWindow class
 *
 * \author Vinet Guillaume <vinet.guillaume@gmail.com>
 * \author Gross David <gdavid.devel@gmail.com>
 * \date 07/01/2009
 */
class MainWindow : public QMainWindow {
    Q_OBJECT

public:
    //! Create a MainWindow object.
    /*!
     * Use show() after a QApplication instance creation to show the window.
     * \param parent the QWidget object parent.
     */
    explicit MainWindow(QWidget *parent = 0);

    //! Destroy a QMainWindow object.
    virtual ~MainWindow();

protected:
    //! Process various key pressing event
    /*!
     * Provide binding between various key pressing and action in the GUI
     */
    void keyPressEvent(QKeyEvent * event);

    //! Called when the user closes the window
    /*!
     * When the user closes the window, TPM will keep running in the systray
     */
    void closeEvent(QCloseEvent *event);

private:
    //! Define actual state of the database.
    enum DbState {
        NONE,
        NEW,
        OPENED,
        LOADED
    };

    //! Define the type of message displayed in the GUI.
    enum MsgType {
        MSG_INFO,
        MSG_ERROR
    };

    //! Define the type of action to be processed for an identifier.
    enum SubmitAction {
        NOACTION,
        SAVE,
        EDIT
    };

    //! Define the quality of a password.
    enum PasswordQuality {
        WEAK1, WEAK2, WEAK3,
        MEDIUM1, MEDIUM2, MEDIUM3,
        STRONG1, STRONG2, STRONG3
    };

    //! Load images for GUI components.
    void setIcons();

    //! Create connections between GUI components.
    void createConnections();

    //! Create the systray icon.
    void createSystrayIcon();

    //! Initialize the first state after components creation for the window.
    void init();

    //! Display a message in the status bar.
    /*!
     * \param type message type.
     * \param msg content to display.
     */
    void statusMsg(MsgType type, const QString &msg);

    //! Apply a style for a widget containing right or wrong information.
    /*!
     * \param widget the widget where style is applied.
     * \param invalid true to apply error style, false to fallback in normal style.
     */
    void setErrorStyle(QWidget *widget, bool invalid);
    
    //! Translate the GUI in the specified language.
    /*!
     * \param language the language.
     */
    void translate(const QString &language);

    //! Instance of TinyPasswordManager for linking actions and the database.
    TinyPasswordManager *m_tpm;

    //! Instance of a MainWindow class form.
    Ui::MainWindow *m_ui;

    //! Actual state of the database.
    DbState m_dbState;

    //! Next action to do for a selected or new identifier.
    SubmitAction m_submitAction;

    //! Timer to hide/show password while displaying identifier information.
    QTimer *m_passwordTimer;

    //! Timer to clear the clipboard which contains the password after several seconds.
    QTimer *m_clipboardTimer;

    //! Translator.
    QTranslator *m_translator;
    
    //! Systray icon.
    QSystemTrayIcon *m_trayIcon;
    
    //! Systray menu.
    QMenu *m_trayIconMenu;
    
    //! Action to quit the application.
    QAction *m_quitAction;
    
public slots:
    //! Hide or show the editor section to add/edit an identifier.
    /*!
     * \param visible set if the editor must be shown.
     */
    void showEditor(bool visible);

    //! Function used to know if the identifier editor is open or not.
    bool editorIsOpen();

    //! Show or hide the password column in the table.
    /*!
     * \param visible set password column visibility.
     */
    void showPasswords(bool visible);

    //! Show the password in clear or shadowed in the editor section.
    /*!
     * \param visible set password field visibility.
     */
    void showClearPassword(bool visible);

    //! Generate a random password for the editor password field.
    void generatePassword();

    //! Open a database file.
    /*!
     * \param path location of the database file to open.
     */
    void openDb(const QString &path = "");

    //! Display a file chooser dialog to open a database from a specific directory selected by user.
    void openDbFrom();

#ifdef WIN32
    //! Display a window to select the directory of firefox and import credentials.
    void importFromFirefox();
#endif

    //! Load an opened database and display content in the table.
    void loadDb();
    
    //! Change the AES private key.
    void changePrivateKey();

    //! Reload database content in the table
    void reloadTableContent();

    //! Copy a selected identifier password  in the clipboard.
    void copyPassword();

    //! Clear editor fields content and style
    void resetEditorFields();

    //! Close the application.
    void quit();

private slots:
    //! Show the TinyPasswordManager about text.
    void about();

    //! Process m_passwordTimer when a timeout occured.
    void autoHidePassword();

    //! Process m_clipboardTimer when a timeout occured.
    void clearClipboard();

    //! Process an action on the database depending of its current state.
    void dbAction();

    //! Execute action when the user request adding a new identifier.
    void addIdentifier();

    //! Execute window changes when the user request editing a new identifier.
    void editIdentifier();

    //! Execute window changes when the user request saving a new/existing identifier.
    void saveIdentifier();

    //! Execute window changes when the user request removing an identifier.
    void removeIdentifier();

    //! Event handler for m_tableIdents.
    void keyEventIdentifier(QKeyEvent *event);
    
	//! Enable or disable m_buttonSubmit.
	void enableSubmitButton();
	
	//! Enable or disable m_buttonDecipher.
	void enableDecipherButton(const QString &key);
	
    //! Mesure password quality when adding new identifier.
    void mesurePasswordQuality(const QString &password);
    
    //! Translate the GUI to French.
    void translateToFrench();
    
    //! Translate the GUI to English.
    void translateToEnglish();
    
    //! Active the systray icon.
    void systrayActivated(QSystemTrayIcon::ActivationReason reason);
};

#endif

